home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 32 / Mac Magazin and MacEasy Magazine CD - Issue 32.iso / Grafik & Text / OzTeX3.0 / MetaPost / Inputs / mfplain.mp < prev    next >
Text File  |  1996-08-24  |  19KB  |  580 lines

  1. % This is the plain MetaPost base that's look like what's described
  2. % in The METAFONTbook.
  3. string base_name, base_version; base_name="mfplain"; base_version="0.62";
  4.  
  5. message "Preloading the plain base, version "&base_version&": preliminaries,";
  6.  
  7. delimiters ();  % this makes parentheses behave like parentheses
  8. def upto = step 1 until enddef; % syntactic sugar
  9. def downto = step -1 until enddef;
  10. def exitunless expr c = exitif not c enddef;
  11. let relax = \;  % ignore the word `relax', as in TeX
  12. let \\ = \; % double relaxation is like single
  13. def ]] = ] ] enddef; % right brackets should be loners
  14. def -- = {curl 1}..{curl 1} enddef;
  15. def --- = .. tension infinity .. enddef;
  16. def ... = .. tension atleast 1 .. enddef;
  17.  
  18. newinternal smoothing, autorounding, turningcheck, granularity;
  19. warningcheck:=1;
  20. tracinglostchars:=1;
  21. smoothing:=1; autorounding:=2;  % These are ignored by MetaPost
  22. turningcheck:=1; granularity:=1;
  23.  
  24. def gobble primary g = enddef;
  25. primarydef g gobbled gg = enddef;
  26. def hide(text t) = exitif numeric begingroup t;endgroup; enddef;
  27. def ??? = hide(interim showstopping:=1; showdependencies) enddef;
  28. def stop expr s = message s; gobble readstring enddef;
  29.  
  30. def interact = % sets up to make "show" commands stop
  31.  hide(showstopping:=1; tracingonline:=1) enddef;
  32.  
  33. def loggingall =        % puts tracing info into the log
  34.  tracingcommands:=3; tracingtitles:=1; tracingequations:=1;
  35.  tracingcapsules:=1; tracingspecs:=2; tracingchoices:=1; tracinglostchars:=1;
  36.  tracingstats:=1; tracingoutput:=1; tracingmacros:=1; tracingrestores:=1;
  37.  enddef;
  38.  
  39. def tracingall =        % turns on every form of tracing
  40.  tracingonline:=1; showstopping:=1; loggingall enddef;
  41.  
  42. def tracingnone =       % turns off every form of tracing
  43.  tracingcommands:=0; tracingtitles:=0; tracingequations:=0;
  44.  tracingcapsules:=0; tracingspecs:=0; tracingchoices:=0; tracinglostchars:=0;
  45.  tracingstats:=0; tracingoutput:=0; tracingmacros:=0; tracingrestores:=0;
  46.  enddef;
  47.  
  48. message " basic constants and mathematical macros,";
  49.  
  50. % numeric constants
  51. newinternal eps,epsilon,infinity,_;
  52. eps := .00049;    % this is a pretty small positive number
  53. epsilon := 1/256/256;   % but this is the smallest
  54. infinity := 4095.99998;    % and this is the largest
  55. _ := -1; % internal constant to make macros unreadable but shorter
  56.  
  57. newinternal mitered, rounded, beveled, butt, squared;
  58. mitered:=0; rounded:=1; beveled:=2; % linejoin types
  59. butt:=0;    rounded:=1; squared:=2; % linecap types
  60.  
  61.  
  62. % pair constants
  63. pair right,left,up,down,origin;
  64. origin=(0,0); up=-down=(0,1); right=-left=(1,0);
  65.  
  66. % path constants
  67. path quartercircle,halfcircle,fullcircle,unitsquare;
  68. fullcircle = makepath pencircle;
  69. halfcircle = subpath (0,4) of fullcircle;
  70. quartercircle = subpath (0,2) of fullcircle;
  71. unitsquare=(0,0)--(1,0)--(1,1)--(0,1)--cycle;
  72.  
  73. % transform constants
  74. transform identity;
  75. for z=origin,right,up: z transformed identity = z; endfor
  76.  
  77. % color constants
  78. color black, white, red, green, blue;
  79. black = (0,0,0);
  80. white = (1,1,1);
  81. red = (1,0,0);
  82. green = (0,1,0);
  83. blue = (0,0,1);
  84.  
  85. % picture constants
  86. picture blankpicture,unitpixel;
  87. blankpicture=nullpicture;
  88. unitpixel=nullpicture; addto unitpixel contour unitsquare;
  89.  
  90. % string constants
  91. string ditto; ditto = char 34; % ASCII double-quote mark
  92.  
  93. % pen constants
  94. def capsule_def(suffix s) primary u = def s = u enddef enddef;
  95. pen pensquare,penrazor,penspeck;
  96. pensquare = makepen(unitsquare shifted -(.5,.5));
  97. penrazor = makepen((-.5,0)--(.5,0)--cycle);
  98. penspeck=pensquare scaled eps;
  99.  
  100. % nullary operators
  101. vardef whatever = save ?; ? enddef;
  102.  
  103. % unary operators
  104. let abs = length;
  105.  
  106. vardef round primary u = u enddef;
  107. vardef hround primary x = x enddef;
  108. vardef vround primary y = y enddef;
  109.  
  110. vardef ceiling primary x = -floor(-x) enddef;
  111.  
  112. vardef byte primary s =
  113.  if string s: ASCII fi s enddef;
  114.  
  115. vardef dir primary d = right rotated d enddef;
  116.  
  117. vardef unitvector primary z = z/abs z enddef;
  118.  
  119. vardef inverse primary T =
  120.  transform T_; T_ transformed T = identity; T_ enddef;
  121.  
  122. vardef counterclockwise primary c =
  123.  if turningnumber c <= 0: reverse fi c enddef;
  124.  
  125. vardef tensepath expr r =
  126.  for k=0 upto length r - 1: point k of r --- endfor
  127.  if cycle r: cycle else: point infinity of r fi enddef;
  128.  
  129. % binary operators
  130.  
  131. primarydef x mod y = (x-y*floor(x/y)) enddef;
  132. primarydef x div y = floor(x/y) enddef;
  133. primarydef w dotprod z = (xpart w * xpart z + ypart w * ypart z) enddef;
  134.  
  135. primarydef x**y = if y=2: x*x else: takepower y of x fi enddef;
  136. def takepower expr y of x =
  137.  if x>0: mexp(y*mlog x)
  138.  elseif (x=0) and (y>0): 0
  139.  else: 1
  140.   if y=floor y:
  141.    if y>=0: for n=1 upto y: *x endfor
  142.    else: for n=_ downto y: /x endfor
  143.    fi
  144.   else: hide(errmessage "Undefined power: " & decimal x&"**"&decimal y)
  145.   fi fi enddef;
  146.  
  147. vardef direction expr t of p =
  148.  postcontrol t of p - precontrol t of p enddef;
  149.  
  150. vardef directionpoint expr z of p =
  151.  a_:=directiontime z of p;
  152.  if a_<0: errmessage("The direction doesn't occur"); fi
  153.  point a_ of p enddef;
  154.  
  155. secondarydef p intersectionpoint q =
  156.  begingroup save x_,y_; (x_,y_)=p intersectiontimes q;
  157.  if x_<0: errmessage("The paths don't intersect"); origin
  158.  else: .5[point x_ of p, point y_ of q] fi endgroup
  159. enddef;
  160.  
  161. tertiarydef p softjoin q =
  162.  begingroup c_:=fullcircle scaled 2join_radius shifted point 0 of q;
  163.  a_:=ypart(c_ intersectiontimes p); b_:=ypart(c_ intersectiontimes q);
  164.  if a_<0:point 0 of p{direction 0 of p} else: subpath(0,a_) of p fi
  165.   ... if b_<0:{direction infinity of q}point infinity of q
  166.    else: subpath(b_,infinity) of q fi endgroup enddef;
  167. newinternal join_radius,a_,b_; path c_;
  168.  
  169. % special operators
  170. vardef incr suffix $ = $:=$+1; $ enddef;
  171. vardef decr suffix $ = $:=$-1; $ enddef;
  172.  
  173. def reflectedabout(expr w,z) =    % reflects about the line w..z
  174.  transformed
  175.   begingroup transform T_;
  176.   w transformed T_ = w;  z transformed T_ = z;
  177.   xxpart T_ = -yypart T_; xypart T_ = yxpart T_; % T_ is a reflection
  178.   T_ endgroup enddef;
  179.  
  180. def rotatedaround(expr z, d) =    % rotates d degrees around z
  181.  shifted -z rotated d shifted z enddef;
  182. let rotatedabout = rotatedaround;   % for roundabout people
  183.  
  184. vardef min(expr u)(text t) = % t is a list of numerics, pairs, or strings
  185.  save u_; setu_ u; for uu = t: if uu<u_: u_:=uu; fi endfor
  186.  u_ enddef;
  187.  
  188. vardef max(expr u)(text t) = % t is a list of numerics, pairs, or strings
  189.  save u_; setu_ u; for uu = t: if uu>u_: u_:=uu; fi endfor
  190.  u_ enddef;
  191.  
  192. def setu_ primary u =
  193.  if pair u: pair u_ elseif string u: string u_ fi;
  194.  u_=u enddef;
  195.  
  196. def flex(text t) =           % t is a list of pairs
  197.  hide(n_:=0; for z=t: z_[incr n_]:=z; endfor
  198.   dz_:=z_[n_]-z_1)
  199.  z_1 for k=2 upto n_-1: ...z_[k]{dz_} endfor ...z_[n_] enddef;
  200. newinternal n_; pair z_[],dz_;
  201.  
  202. def superellipse(expr r,t,l,b,s)=
  203.  r{up}...(s[xpart t,xpart r],s[ypart r,ypart t]){t-r}...
  204.  t{left}...(s[xpart t,xpart l],s[ypart l,ypart t]){l-t}...
  205.  l{down}...(s[xpart b,xpart l],s[ypart l,ypart b]){b-l}...
  206.  b{right}...(s[xpart b,xpart r],s[ypart r,ypart b]){r-b}...cycle enddef;
  207.  
  208. vardef interpath(expr a,p,q) =
  209.  for t=0 upto length p-1: a[point t of p, point t of q]
  210.   ..controls a[postcontrol t of p, postcontrol t of q]
  211.    and a[precontrol t+1 of p, precontrol t+1 of q] .. endfor
  212.  if cycle p: cycle
  213.  else: a[point infinity of p, point infinity of q] fi enddef;
  214.  
  215. vardef solve@#(expr true_x,false_x)= % @#(true_x)=true, @#(false_x)=false
  216.  tx_:=true_x; fx_:=false_x;
  217.  forever: x_:=.5[tx_,fx_]; exitif abs(tx_-fx_)<=tolerance;
  218.  if @#(x_): tx_ else: fx_ fi :=x_; endfor
  219.  x_ enddef; % now x_ is near where @# changes from true to false
  220. newinternal tolerance, tx_,fx_,x_; tolerance:=.1;
  221.  
  222. message " macros for converting units,";
  223.  
  224. newinternal bpppix_, bp_per_pixel;  % drawing is done in `pixel' units
  225. bpppix_:=0.02;
  226.  
  227. mm*bpppix_=2.83464;      pt*bpppix_=0.99626;
  228. dd*bpppix_=1.06601;      bp*bpppix_=1;
  229. cm*bpppix_=28.34645;     pc*bpppix_=11.95517;
  230. cc*bpppix_=12.79213;     in*bpppix_=72;
  231.  
  232. mm#=2.84528;      pt#=1;        dd#=1.07001;      bp#=1.00375;
  233. cm#=28.45276;     pc#=12;       cc#=12.84010;     in#=72.27;
  234.  
  235. newinternal hppp, vppp;
  236. hppp:=pt;   vppp:=pt;
  237.  
  238. newinternal blacker, o_correction; % device-oriented corrections
  239.  
  240. def define_pixels(text t) =
  241.  forsuffixes $=t: $:=$.#*pt; endfor enddef;
  242. def define_blacker_pixels(text t) =
  243.  forsuffixes $=t: $:=$.#*pt+blacker; endfor enddef;
  244. def define_corrected_pixels(text t) =
  245.  forsuffixes $=t: $:=$.#*pt*o_correction; endfor enddef;
  246.  
  247. def define_whole_pixels = define_pixels enddef;
  248. def define_whole_vertical_pixels = define_pixels enddef;
  249. def define_good_x_pixels = define_pixels enddef;
  250. def define_good_y_pixels = define_pixels enddef;
  251. def define_whole_blacker_pixels = define_blacker_pixels enddef;
  252. def define_whole_vertical_blacker_pixels = define_blacker_pixels enddef;
  253. def define_horizontal_corrected_pixels = define_corrected_pixels enddef;
  254.  
  255. def lowres_fix(text t) expr ratio = enddef;
  256.  
  257. message " macros and tables for various modes of operation,";
  258.  
  259. transform currenttransform;
  260. def t_ = transformed currenttransform enddef;
  261. let o_=\; let _o_=\;
  262.  
  263. def mode_setup =
  264.  if unknown mode: mode=proof; fi
  265.  numeric aspect_ratio; transform currenttransform;
  266.  scantokens if string mode:("input "&mode) else: mode_name[mode] fi;
  267.  if unknown mag: mag=1; fi
  268.  if unknown aspect_ratio: aspect_ratio=1; fi
  269.  bp_per_pixel:=bpppix_*mag;
  270.  scantokens extra_setup; % the user's special last-minute adjustments
  271.  if unknown currenttransform: currenttransform=identity; fi
  272.  clearit;
  273.  pickup pencircle scaled (.4pt+blacker);
  274.  enddef;
  275. def smode = string mode; mode enddef;
  276. string extra_setup, mode_name[];
  277. extra_setup="";          % usually there's nothing special to do
  278.  
  279. vardef magstep primary m = mexp(46.67432m) enddef;
  280.  
  281. def mode_def suffix $ =
  282.  $:=incr number_of_modes;
  283.  mode_name[$]:=str$ & "_";
  284.  expandafter quote def scantokens mode_name[$] enddef;
  285. newinternal number_of_modes;
  286.  
  287.  
  288. newinternal proofing; % <0 to supress output; >1 to do labels
  289. color proofcolor;     % color for output when proofing>0
  290. proofcolor =.3[white,black];
  291. color background;
  292. background = white;
  293.  
  294. % proof mode: for initial design of characters
  295. mode_def proof =
  296.  proofing:=2;                   % yes, we're making full proofs
  297.  fontmaking:=0;                 % no, we're not making a font
  298.  tracingtitles:=1;              % yes, show titles online
  299.  blacker:=0;                    % no additional blackness
  300.  o_correction:=1;               % no reduction in overshoot
  301.  if unknown mag: mag=36; else: mag:=36mag; fi
  302.  enddef;
  303.  
  304. % smoke mode: for label-free proofs to mount on the wall
  305. mode_def smoke =
  306.  proof_;                        % same as proof mode, except:
  307.  proofing:=1;                   % yes, we're making unlabeled proofs
  308.  proofcolor:=black;             % with solid black pixels
  309.  let makebox=maketicks;         % make the boxes less obtrusive
  310.  if unknown mag: mag=36; else: mag:=36mag; fi
  311.  enddef;
  312.  
  313. % lowres mode: for certain devices that print 200 pixels per inch
  314. mode_def lowres =
  315.  proofing:=0;                   % no, we're not making proofs
  316.  fontmaking:=1;                 % yes, we are making a font
  317.  tracingtitles:=0;              % no, don't show titles at all
  318.  blacker:=0;                    % no extra blackness with PostScript
  319.  o_correction:=1;               % no reduction in overshoot
  320.  enddef;
  321.  
  322. localfont:=lowres;      % the mode most commonly used to make fonts
  323.  
  324. % It is not likely that additional modes are needed, but if they are,
  325. % additional mode_def commands should be in another input file that
  326. % gets loaded after the PLAIN base.  The auxiliary file should set
  327. % base_version:=base_version&"/localname".
  328.  
  329.  
  330. message " macros for drawing and filling,";
  331.  
  332. def pc_ =
  333.   hide(if proofing>0: def pc_=do_pc_ enddef; else: def pc_= enddef; fi) pc_
  334. enddef;
  335. def do_pc_ = withcolor proofcolor enddef;
  336.  
  337. linejoin:=rounded;               % parameters that effect drawing
  338. linecap:=rounded;
  339. miterlimit:=10;
  340.  
  341. pen currentpen;
  342. picture currentpicture;
  343.  
  344. def fill expr c = addto currentpicture contour c t_ pc_ enddef;
  345. def draw expr p =
  346.   addto currentpicture
  347.   if picture p:
  348.     also p
  349.   else:
  350.     doublepath p t_ withpen currentpen
  351.   fi
  352.   pc_
  353. enddef;
  354. def filldraw expr c =
  355.   addto currentpicture contour c t_ withpen currentpen
  356.   pc_ enddef;
  357. def drawdot expr z =
  358.   addto currentpicture contour makepath currentpen shifted z
  359.   t_ pc_ enddef;
  360.  
  361. def unfill expr c = fill c withcolor background enddef;
  362. def undraw expr p = draw p withcolor background enddef;
  363. def unfilldraw expr c = filldraw c withcolor background enddef;
  364. def undrawdot expr z = drawdot z withcolor background enddef;
  365. def erase text t =
  366.   def _e_ = withcolor background hide(def _e_=enddef;) enddef;
  367.   t _e_
  368. enddef;
  369. def _e_= enddef;
  370.  
  371. def cutdraw text t =
  372.   begingroup interim linecap:=butt; draw t _e_; endgroup enddef;
  373.  
  374. def pickup secondary q =
  375.  if numeric q: numeric_pickup_ else: pen_pickup_ fi q enddef;
  376. def numeric_pickup_ primary q =
  377.  if unknown pen_[q]: errmessage "Unknown pen"; clearpen
  378.  else: currentpen:=pen_[q];
  379.   pen_lft:=pen_lft_[q];
  380.   pen_rt:=pen_rt_[q];
  381.   pen_top:=pen_top_[q];
  382.   pen_bot:=pen_bot_[q];
  383.   currentpen_path:=pen_path_[q] fi; enddef;
  384. def pen_pickup_ primary q =
  385.   currentpen:=q;
  386.   pen_lft:=xpart penoffset down of currentpen;
  387.   pen_rt:=xpart penoffset up of currentpen;
  388.   pen_top:=ypart penoffset left of currentpen;
  389.   pen_bot:=ypart penoffset right of currentpen;
  390.   path currentpen_path; enddef;
  391. newinternal pen_lft,pen_rt,pen_top,pen_bot,pen_count_;
  392.  
  393. vardef savepen = pen_[incr pen_count_]=currentpen;
  394.  pen_lft_[pen_count_]=pen_lft;
  395.  pen_rt_[pen_count_]=pen_rt;
  396.  pen_top_[pen_count_]=pen_top;
  397.  pen_bot_[pen_count_]=pen_bot;
  398.  pen_path_[pen_count_]=currentpen_path;
  399.  pen_count_ enddef;
  400.  
  401. def clearpen = currentpen:=nullpen;
  402.  pen_lft:=pen_rt:=pen_top:=pen_bot:=0;
  403.  path currentpen_path;
  404.  enddef;
  405. def clear_pen_memory =
  406.  pen_count_:=0;
  407.  numeric pen_lft_[],pen_rt_[],pen_top_[],pen_bot_[];
  408.  pen currentpen,pen_[];
  409.  path currentpen_path, pen_path_[];
  410.  enddef;
  411.  
  412. vardef lft primary x = x + if pair x: (pen_lft,0) else: pen_lft fi enddef;
  413. vardef rt primary x = x + if pair x: (pen_rt,0) else: pen_rt fi enddef;
  414. vardef top primary y = y + if pair y: (0,pen_top) else: pen_top fi enddef;
  415. vardef bot primary y = y + if pair y: (0,pen_bot) else: pen_bot fi enddef;
  416. vardef good.x primary x = x enddef;
  417. vardef good.y primary y = y enddef;
  418. vardef good.lft primary z = z enddef;
  419. vardef good.rt primary z = z enddef;
  420. vardef good.top primary z = z enddef;
  421. vardef good.bot primary z = z enddef;
  422.  
  423. vardef penpos@#(expr b,d) =
  424.  (x@#r-x@#l,y@#r-y@#l)=(b,0) rotated d;
  425.  x@#=.5(x@#l+x@#r); y@#=.5(y@#l+y@#r) enddef;
  426.  
  427. def penstroke text t =
  428.  forsuffixes e = l,r: path_.e:=t; endfor
  429.  fill path_.l -- reverse path_.r -- cycle enddef;
  430. path path_.l,path_.r;
  431.  
  432. message " macros for proof labels and rules,";
  433.  
  434. string defaultfont;
  435. newinternal defaultscale, labeloffset;
  436. defaultfont = "cmr10";
  437. defaultscale := 1;
  438. labeloffset := 3;
  439.  
  440. vardef makelabel@#(expr s,z) = % puts string s near point z
  441.   picture p;
  442.   if known z:
  443.     p = s infont defaultfont scaled (defaultscale/bp_per_pixel);
  444.     draw p shifted (z t_ + labeloffset/bp_per_pixel*laboff@# -
  445.        (labxf@#*lrcorner p + labyf@#*ulcorner p
  446.          + (1-labxf@#-labyf@#)*llcorner p
  447.        )
  448.     ) withcolor black;
  449.     interim linecap:=rounded;
  450.     draw z withpen pencircle scaled (3/bp_per_pixel) withcolor black;
  451.   fi
  452. enddef;
  453.  
  454. string lcode_;  % just in case someone refers to this
  455. pair laboff, laboff.lft, laboff.rt, laboff.top, laboff.bot;
  456. laboff.lft=(-1,0);   labxf.lft=1;   labyf.lft=.5;
  457. laboff.rt =(1,0);    labxf.rt =0;   labyf.rt =.5;
  458. laboff.bot=(0,-1);   labxf.bot=.5;  labyf.bot=1;
  459. laboff.top=(0,1);    labxf.top=.5;  labyf.top=0;
  460. laboff=laboff.top;   labxf=labxf.top; labyf=labyf.top;
  461. % There could be fancy code to keep labels from overlapping!
  462.  
  463. vardef labels@#(text t) =
  464.  if proofing>1: forsuffixes $=t:
  465.   makelabel@#(str$,z$); endfor
  466.  fi enddef;
  467. vardef penlabels@#(text t) =
  468.  if proofing>1: forsuffixes $$=l,,r: forsuffixes $=t:
  469.   makelabel@#(str$.$$,z$.$$); endfor endfor
  470.  fi enddef;
  471.  
  472. def range expr x = numtok[x] enddef;
  473. def numtok suffix x=x enddef;
  474. tertiarydef m thru n =
  475.  m for x=m+1 step 1 until n: , numtok[x] endfor enddef;
  476.  
  477. def proofrule(expr w,z) =
  478.   begingroup interim linecap:=squared;
  479.   draw w..z withpen pencircle scaled (.4/bp_per_pixel) withcolor black;
  480.   endgroup
  481. enddef;
  482. def screenrule(expr w,z) = enddef;
  483. pen rulepen;
  484.  
  485. def makegrid(text xlist,ylist) =
  486.  xmin_ := min(xlist); xmax_ := max(xlist);
  487.  ymin_ := min(ylist); ymax_ := max(ylist);
  488.  for x=xlist: proofrule((x,ymin_), (x,ymax_)); endfor
  489.  for y=ylist: proofrule((xmin_,y), (xmax_,y)); endfor
  490.  enddef;
  491.  
  492. vardef titlefont suffix $ = enddef;
  493. vardef labelfont suffix $ = defaultfont:=str$ enddef;
  494. vardef grayfont suffix $ = enddef;
  495. vardef slantfont suffix $ = enddef;
  496. def proofoffset primary z = enddef;
  497. vardef proofrulethickness expr x =
  498.  rulepen := pencircle scaled x enddef;
  499.  
  500. message " macros for character and font administration,";
  501.  
  502. def beginchar(expr c,w_sharp,h_sharp,d_sharp) =
  503.  begingroup
  504.  charcode:=if known c: byte c else: 0 fi;
  505.  charwd:=w_sharp;      charht:=h_sharp;       chardp:=d_sharp;
  506.  w:=charwd*pt; h:=charht*pt; d:=chardp*pt;
  507.  charic:=0; clearxy; clearit; clearpen; scantokens extra_beginchar;
  508.  enddef;
  509.  
  510. def italcorr expr x_sharp = if x_sharp>0: charic:=x_sharp fi enddef;
  511.  
  512. def change_width = enddef;
  513.  
  514. def endchar =
  515.  scantokens extra_endchar;
  516.  if proofing>0: makebox(proofrule); fi
  517.  chardx:=w;     % desired width of the character in pixels
  518.  shipit;
  519.  endgroup enddef;
  520.  
  521. string extra_beginchar, extra_endchar;
  522. extra_beginchar=extra_endchar="";
  523.  
  524. def makebox(text r) =
  525.  for y=0,h,-d: r((0,y),(w,y)); endfor % horizontals
  526.  for x=0,w:   r((x,-d),(x,h)); endfor % verticals
  527.  if charic<>0: r((w+charic*pt,h),(w+charic*pt,.5h)); fi
  528.  enddef;
  529.  
  530. def maketicks(text r) =
  531.  for y=0,h,-d: r((0,y),(10,y)); r((w-10,y),(w,y)); endfor
  532.  for x=0,w: r((x,10-d),(x,-d)); r((x,h-10),(x,h)); endfor
  533.  if charic<>0: r((w+charic*pt,h-10),(w+charic*pt,h)); fi
  534.  enddef;
  535.  
  536. def font_size expr x = designsize:=x enddef;
  537. def font_slant expr x = fontdimen 1: x enddef;
  538. def font_normal_space expr x = fontdimen 2: x enddef;
  539. def font_normal_stretch expr x = fontdimen 3: x enddef;
  540. def font_normal_shrink expr x = fontdimen 4: x enddef;
  541. def font_x_height expr x = fontdimen 5: x enddef;
  542. def font_quad expr x = fontdimen 6: x enddef;
  543. def font_extra_space expr x = fontdimen 7: x enddef;
  544.  
  545. def font_identifier expr x = font_identifier_:=x enddef;
  546. def font_coding_scheme expr x = font_coding_scheme_:=x enddef;
  547. string font_identifier_, font_coding_scheme_;
  548. font_identifier_=font_coding_scheme_="UNSPECIFIED";
  549.  
  550. message "and a few last-minute items.";
  551.  
  552. vardef z@#=(x@#,y@#) enddef;
  553.  
  554. def openit = enddef;
  555. def showit = enddef;
  556.  
  557. def clearxy = save x,y enddef;
  558. def clearit = currentpicture:=nullpicture enddef;
  559. def shipit =
  560.   if proofing>=0:
  561.     shipout currentpicture transformed
  562.       (identity shifted (xoffset,yoffset) scaled bp_per_pixel)
  563.   fi
  564. enddef;
  565. def cullit = enddef;
  566. newinternal xoffset, yoffset;
  567.  
  568. def screenchars = enddef;
  569. def screenstrokes = enddef;
  570. def imagerules = enddef;
  571. def gfcorners = enddef;
  572. def nodisplays = enddef;
  573. def notransforms = let t_ = \ enddef;
  574.  
  575. let bye = end; outer end,bye;
  576.  
  577. clear_pen_memory;     % initialize the `savepen' mechanism
  578. mode_setup;           % establish proof mode as the default
  579. numeric mode,mag;     % but leave mode and mag undefined
  580.